package gagak.framework.web.adapter;


import gagak.framework.web.annonation.Nullable;
import gagak.framework.web.context.MvcApplicationContext;
import gagak.framework.web.context.MvcContextApplicationHolder;
import gagak.framework.web.param.HandlerMethod;
import gagak.framework.web.param.MethodParameter;
import gagak.framework.web.paramresovler.HandlerMethodArgumentResolver;
import gagak.framework.web.paramresovler.HandlerMethodArgumentResolverComposite;
import gagak.framework.web.paramresovler.InvocableHandlerMethod;
import gagak.framework.web.support.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/*
 * @program: ce
 * @description: requestmapping类型的适配器
 * @author: houhong
 * @create: 2022-11-25 17:02
 */
public class RequestMappingMethodAdapter extends AbstractMethodHandlerAdapter {

    private HttpServletRequest request;

    private HttpServletResponse response;


    /*
     * 真正干活:做url 处理
     * 1： 传递handlerMethod
     * 2： 从Request 里面去获取到当前handeler 所需要的参数 封装成实际参数
     * 3： 然后解析@RequestBody,@RequestParam  这些参数解析 委托给参数解析器处理
     * 4： 反射执行handle 然后获取结果，将结果进行强转
     * 5： 将结果序列化成json 返回。  如果为空，就不做处理
     */
    @Override
    public Object handle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        this.request = request;
        this.response = response;
        HandlerMethod handlerMethod = (HandlerMethod) handler;

        try {
            return invokeBusinessMethod(request, response, handlerMethod);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }

        return null;
    }


    /*
     * @return {@link Object}
     * @Author houhong
     * @Description //TODO 反射执行
     * @Date 7:58 下午 2022/11/25
     */
    protected Object invokeBusinessMethod(HttpServletRequest request,
                                          HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

        ServletWebRequest servletWebRequest = new ServletWebRequest(request, response);
        //将当前请求request封装成一个InvocableHandlerMethod 在这里面 做了请求流程的封装
        InvocableHandlerMethod invocableHandlerMethod = new InvocableHandlerMethod(handlerMethod);


        /*
         *  设置处理器进去
         */
        MvcApplicationContext mvcApplicationContext = MvcContextApplicationHolder.getMvcApplicationContext();

        List<HandlerMethodArgumentResolver> methodArgumentResolvers = mvcApplicationContext.getHandlerMethodArgumentResolvers();

        HandlerMethodArgumentResolverComposite resolverComposite = new HandlerMethodArgumentResolverComposite();
        resolverComposite.addResolvers(methodArgumentResolvers);
        invocableHandlerMethod.setHandlerMethodArgumentResolvers(resolverComposite);

       /* //设置返回参数解析器
        HandlerMethodReturnValueHandlerComposite returnValueHandlerCompos = new HandlerMethodReturnValueHandlerComposite();
        List<HandlerMethodReturnValueHandler> returnValueHandlers = mvcApplicationContext.getHandlerMethodReturnValueHandlers();
        returnValueHandlerCompos.addHandlers(returnValueHandlers);
        invocableHandlerMethod.setReturnValueHandlers(returnValueHandlerCompos);*/

        //调用封装的执行链进行执行
        return invocableHandlerMethod.invokeAndHandle(servletWebRequest);

    }


    private Object resolveProvidedArgument(MethodParameter parameter, @Nullable Object... providedArgs) {
        if (providedArgs == null) {
            return null;
        }
        for (Object providedArg : providedArgs) {
            if (parameter.getParameterType().isInstance(providedArg)) {
                return providedArg;
            }
        }
        return null;
    }


}